package biz

import (
	"beetle/internal/model"
	"beetle/internal/pkg/constant"
	"beetle/internal/pkg/tool"
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"io/ioutil"
	"net/http"
	"strings"
)

// parseData 解析数据
func parseData(db *gorm.DB, record *model.RedisRecord) (string, error) {

	switch record.RequestMode {
	case constant.JSON:
		if record.Data == "" {
			return "", errors.New("数据为空")
		}
		return record.Data, nil
	case constant.SQL:
		// todo 执行SQL
		return execSQL(db, record.Data)
	case constant.HttpGet:
		var mp map[string]string
		err := json.Unmarshal([]byte(record.Header), &mp)
		if err != nil {
			return "", err
		}
		return httpGet(record.Data, mp)
	}
	return "", errors.New("请求方式错误")
}

// execSQL执行SQL
func execSQL(db *gorm.DB, sql string) (string, error) {
	rows, err := db.Raw(sql).Rows()
	if err != nil {
		return "", err
	}
	defer rows.Close()
	var list []map[string]interface{}
	for rows.Next() {
		var mp map[string]interface{}
		db.ScanRows(rows, &mp)
		list = append(list, mp)
	}
	bytes, err := json.MarshalIndent(list, "", " ")
	if err != nil {
		return "", err
	}
	return string(bytes), nil
}

// convertData构造数据
func convertData(dataType string, key string, data string) map[string]string {

	result := make(map[string]string)
	if dataType != "" {
		datatTypes := strings.Split(dataType, ",")
		for i := range datatTypes {
			switch constant.DataType(datatTypes[i]) {
			case constant.REDIS_LIST:
				var buf bytes.Buffer
				json.Indent(&buf, []byte(data), "", "  ")

				if !tool.IsValid(key) {
					// TODO 记录日志
					return nil
				}

				var placeholder = tool.Between(key)
				cacheKey := tool.Replace(key, placeholder, fmt.Sprintf("%s", "all"))
				result[cacheKey] = buf.String()

			case constant.REDIS_GROUP:
				// TODO 遍历切片对切片进行分组
				temp := handleGroup(key, data)
				for k, v := range temp {
					result[k] = v
				}
			case constant.REDIS_MAP:
				temp := handleMap(key, data)
				for k, v := range temp {
					result[k] = v
				}
			}
		}
	}
	return result
}

// createRequest 创建request请求
func createRequest(url string, header map[string]string) *http.Request {
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil
	}
	req.Header.Set("Content-Type", "application/json;charset=UTF-8")
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Accept-Charset", "utf-8")

	for k, v := range header {
		req.Header.Set(k, v)
	}
	return req
}

// httpGet
func httpGet(url string, header map[string]string) (string, error) {
	client := &http.Client{}
	req := createRequest(url, header)
	resp, err := client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	return string(body), nil
}
